Skip to content

Indoor humidity and air-conditioning dehumidification - #4164

Open
cathyxinchangli wants to merge 66 commits into
ESCOMP:masterfrom
cathyxinchangli:dehumidification_pr
Open

Indoor humidity and air-conditioning dehumidification#4164
cathyxinchangli wants to merge 66 commits into
ESCOMP:masterfrom
cathyxinchangli:dehumidification_pr

Conversation

@cathyxinchangli

@cathyxinchangli cathyxinchangli commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Description of changes

The code changes add indoor humidity and air-conditioning dehumidification to the CLMU BEM. It prognoses indoor specific humidity, calculates sensible cooling and latent dehumidification loads, and diagnoses condensate production and routes the condensate into urban runoff. The behavior is controlled by an integer CLM namelist variable, building_humidity_mode:

  • 0: use the existing CLMU formulation without indoor humidity or AC dehumidification;
  • 1: enable indoor humidity and latent heat exchange, but no AC dehumidification (requires prognostic building temperature, building_temp_method=1); and
  • 2: enable indoor humidity, latent heat exchange, dehumidification load, and condensate production (requires prognostic building temperature, urban_hac to be ON or ON_WASTEHEAT and urban_explicit_ac=.true.).

The default is set to 0 to ensure bit-for-bit reproducibility with the original scheme.

Specific notes

Contributors other than yourself, if any:
Lei Zhao (@Face2sea), Zhiwen Luo, Keith Oleson (@olyson), Yifan Cheng (@yifanc17), Xiaoxiong Xie, Alvin C. G. Varquez, Mitsuna Sekiya

CTSM issues resolved or otherwise addressed, if any:
Resolves #4162

If answers are expected to change, describe (delete this line otherwise):
Results remain bit-for-bit under building_humidity_mode=0. Comparing building_humidity_mode=1 with 0, two new variables are added (QBUILD, RHBUILD), and VENTILATION and EFLXBUILD changes because they now include latent heat exchanges between indoors and outdoors, and URBAN_AC and URBAN_HEAT changes slightly because of the changes in ventilation and higher heat capacity of moist air. Comparing building_humidity_mode=2 with 1, three more new variables (URBAN_AC_SEN, QCOND_FROM_AC, QCOND_FROM_AC_LUN) are added, and URBAN_AC increases because it now includes sensible (for cooling) and latent (for dehumidification) heat components of urban AC demand. URBAN_HEAT, VENTILATION, EFLXBUILD, WASTEHEAT changes slightly as an indirect results of the changes in AC.

Any user interface changes (namelist or namelist defaults changes)?
Yes, building_humidity_mode is added as a namelist variable.

Testing planned or performed, if any:
Results of the tests are under /glade/work/xinchang/03b_Dehumidification/05_pull_request/.

  • The physics of the scheme is validated in the accompanying publication;
  • Land-only simulations under DEBUG mode show Mode 0 is bit-for-bit as original CLMU, and Mode 2 is bit-for-bit as the validated version of the scheme (building_humidity_regression_diagnostics.ipynb);
  • Key variables for Mode 0, 1, and 2 are compared (building_humidity_mode_diagnostics.ipynb);
  • Restart behavior is tested for all three modes. All history fields except QAF were bit-for-bit after a continues 2-month run and a 1-month, 1-resubmit run in all three modes (building_humidity_restart_diagnostics.ipynb). The fact that the QAF discrepancy exists under Mode 0 (which is bit-for-bit as the original CLMU) seems to suggest this is not a problem of the new scheme. The reason might be because QAF history field is computed from the patch-level variable, whereas the QAF restart field is saved from the land-unit-level variable.

Requirements before merge:

  • The code in this PR branch builds with no errors.
  • The code in this PR branch runs with no errors. Briefly describe tested configuration(s): land-only, 1-degree simulations run for 1 year under DEBUG mode ran without errors. The scripts used to run the simulations are in /glade/u/home/xinchang/cases_dehumidification/.
  • This either (a) does not change answers, (b) it only changes answers at roundoff level, or (c) I have performed a scientific evaluation of the answer changes. Which?: (c)

cathyxinchangli and others added 30 commits April 30, 2024 17:27
Define, initialize, create history field, and create restart variable for `q_building`, internal building air specific humidity.

Add argument "is_prog_buildtemp" to various subroutines to only initialize/create restart file for `q_building` if using prognostic temperature method.
1. define `q_building_max` as a constant in clm_varcon.F90
2. add latent heat component to `eflx_ventilation` and `eflx_building`
1. update `q_building` for the current time step assuming perfect mixing;
2. implement dehumidification process under explicit-AC-adoption scheme: introduce local variable `eflx_urban_ac_sat_lat` to represent latent heat load being removed. Dehumidification under original scheme is not implemented. Humidification for heating is also not implemented.
3. reset `q_building` based on `eflx_urban_ac_sat_lat`.
add one line to account for when there is no sensible heat load and only latent heat load.
Revoke some changes from before b/c they may not be necessary.
Change all waterdiagnostic_type into waterdiagnosticbulk_type to try to fix the error of no "water_inst%waterdiagnostic_inst" defined when trying to call it in clm_driver.F90.
1. Define RH_building, add hist field
2. Convert RH_building_max (RH setpoint) to q_building_max (spec hum setpoint)
3. Calculate RH_building from q_building
Change density and specific heat capacity from dry air to humid air.

NOT DONE IN THIS COMMIT but may need to change pressure from forc_pbot to pstd in some QSat() calls to maintain consistency with original code.
change all pressure in QSat() calls to pstd for consistency with original code (i.e., in calculation of rho_dair).
This reverts commit 5f39e20.

Changing back to using bottom layer of atmos. pressure to calculate rh_building, based on email discussion with Keith. Need another commit to update the use of pressure in density of humid air calculation.
Change all pressure from pstd (standard pressure) to forc_pbot (bottom layer atmos. forcing pressure).
1. Add variable 'eflx_urban_ac_sen_lun` and hist field `URBAN_AC_SEN`
2. Output `URBAN_AC_SEN` before latent heat is calculated
1. Calculate total condensed water, and convert it to water flux per impervious surface area in UrbBuildTempOlesonMod.F90 (incl. a write statement);
2. Add new variable `qflx_condensate_from_ac_col`  in WaterFluxType.F90;
3. Update BuildingTemperature() calls
1. calculate condensate flux w.r.t. urban land unit area in BuildingTemperature subroutine;
2. add condensate flux to surface runoff in TotalSurfaceRunoff subroutine.
`qflx_condensate_from_ac_col` is added to column-level water balance check, and `qflx_condensate_from_ac_grc` is calculated & added to grid-cell-level water balance check.
Note these two terms have not been added to the error messages.
@cathyxinchangli

Copy link
Copy Markdown
Contributor Author

Thank you so much, @olyson! That's great to know for future reference. Seems like @wwieder beat me to it and converted it from draft to ready (thanks Will!). Let me know if there's anything else I could do in the meantime!

@olyson

olyson commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Next step would be a paired review with @slevis-lmwg , you, and myself, to go over the code one more time. You could just email Sam and myself about your availability for meeting via zoom next week if possible.

Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
@slevis-lmwg slevis-lmwg moved this from Todo to In Progress in LMWG: Sprint Planning Board Sep 1, 2026
@slevis-lmwg slevis-lmwg added the test: aux_clm Pass aux_clm suite before merging label Sep 1, 2026

@slevis-lmwg slevis-lmwg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I requested a few changes. I will save the "approve" for when they are done, since at that time I will also need to submit testing in prep. for merging the PR.

@cathyxinchangli I also promised an example of the labeled if-statements. In biogeochem/CNBalanceCheckMod.F90 you can find this example:

if_notfates: if (.not. use_fates_bgc) then
end if if_notfates

I recommend short but intuitive labels, as we try to do with variable names.

# Figure out number of tests that will run
#
my $ntests = 3407;
my $ntests = 3413;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slevis-lmwg note to self for when updates to the PR are complete, and I can start testing:

  • ./build-namelist_test.pl
  • aux_clm

Comment thread src/biogeophys/UrbanParamsType.F90 Outdated
Comment thread src/biogeophys/UrbanParamsType.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment thread src/biogeophys/UrbBuildTempOleson2015Mod.F90 Outdated
Comment on lines +600 to +609
if (IsACDehumidificationEnabled()) then
this%qflx_condensate_from_ac_col(begc:endc) = 0.0_r8
call hist_addfld1d ( &
fname=this%info%fname('QCOND_FROM_AC'), &
units='mm/s', &
avgflag='A', &
long_name=this%info%lname('Condensed water flux from AC dehumidification'), &
ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf')
this%qflx_condensate_from_ac_lun(begl:endl) = 0.0_r8
end if

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some questions here:

  1. I see ival = 0.0_r8 a few lines up, so is it redundant here to set
this%qflx_condensate_from_ac_col(begc:endc) = 0.0_r8
this%qflx_condensate_from_ac_lun(begl:endl) = 0.0_r8
  1. If so, I could see keeping the first one because we have a line like that before every call hist_addfld1d, but I would probably remove the second.
  2. I suggest adding a comment explaining why you initialize these to zero, since most others get initialized to spval.
  3. Regarding this and other new calls to hist_addfld1d, I wonder if placing them in if-statements means that they will not appear in the master field list that we post in the User's Guide (@olyson do you know off the top of your head?):
    https://escomp.github.io/CTSM//users_guide/setting-up-and-running-a-case/history_fields_nofates.html

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding 4., although I don't know how the master field list is generated, I believe they will appear. Judging from a few variables I added that are inactive by default, that do appear in the lastest master field list, e.g., Tair_from_atm.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. You might be right; it could be redundant to set both. I could not recall if I tested all the alternatives, but I agree with you for point 2.
  2. Yep, the second assignment was left over from before when I had qflx_condensate_from_ac_lun as a history field. It is removed now.
  3. Added a comment to explain why they were initialized to 0.0_r8 before the AllocateVar1d() calls.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure about 4, but here's Codex's answer to it in case it's helpful:
"I checked the generation path. The master table is written from fields registered during the documentation test run. Registered-but-inactive fields appear, but a field whose hist_addfld1d call is skipped does not. Thus QCOND_FROM_AC requires mode 2 in the generation run; the same distinction applies to other mode-dependent fields. I suggest retaining the runtime guards and documenting these fields using an appropriately configured run.

Evidence: src/main/histFileMod.F90:405 and doc/source/users_guide/setting-up-and-running-a-case/README_history_fields_files. Runtime generation in the three updated cases confirms this behavior: mode 0 lists none of the four fields; mode 1 lists QBUILD and RHBUILD; mode 2 lists all four."

@slevis-lmwg slevis-lmwg Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @cathyxinchangli
I will run the aux_clm test ERP_P64x2_D_Ld3.f10_f10_mg37.I1850Clm50BgcCrop.derecho_gnu.clm-extra_outputs that writes a copy of the master field list. If necessary, I may update the user_nl_clm to ensure the new fields show up.

@slevis-lmwg

Copy link
Copy Markdown
Contributor

Oh, in my review I forgot to ask about this. Up at the top you have the comment "includes required documentation updates" but I did not see updates to the .rst files (Technote/User's Guide). @olyson are such updates waiting for the conversion of the MSWord doc to .rst?

@olyson

olyson commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Oh, in my review I forgot to ask about this. Up at the top you have the comment "includes required documentation updates" but I did not see updates to the .rst files (Technote/User's Guide). @olyson are such updates waiting for the conversion of the MSWord doc to .rst?

My original thought was to add an overview of the new parameterization to the existing urban chapter, similar to the overview of the explicit AC parameterization now in the urban chapter. But now that you've made such good progress incorporating the original tech note into the docs, we could add a more detailed description of this parameterization. I guess it would need to wait for the incorporation of your branch into the docs. We'd also need to add the detailed equations for the explicit AC parameterization. @cathyxinchangli , @slevis-lmwg , what do you think?

@cathyxinchangli

cathyxinchangli commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Oh, in my review I forgot to ask about this. Up at the top you have the comment "includes required documentation updates" but I did not see updates to the .rst files (Technote/User's Guide). @olyson are such updates waiting for the conversion of the MSWord doc to .rst?

My original thought was to add an overview of the new parameterization to the existing urban chapter, similar to the overview of the explicit AC parameterization now in the urban chapter. But now that you've made such good progress incorporating the original tech note into the docs, we could add a more detailed description of this parameterization. I guess it would need to wait for the incorporation of your branch into the docs. We'd also need to add the detailed equations for the explicit AC parameterization. @cathyxinchangli , @slevis-lmwg , what do you think?

Good catch @slevis-lmwg, I had unticked that task about documentation to indicate this pr did not accomplish that, but forgot I already answered (b) at the end. I can remove it for clarity.

I feel if we are adding more than the documentation about indoor humidity & dehumidification, it might make more sense to start another PR just for that to help keep the records separated. It'd also avoid delaying the merging. But if you both or others on the CTSM team think we should have both the documentation and the code ready as part of this PR, then we can add that too. The descriptions and equations for both explicit AC adoption scheme and this scheme are in the papers, and we just need to consolidate them.

@wwieder

wwieder commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Would these steps be productive?

  1. create a documentation issue related to this PR
  2. merge this PR, and
  3. address step 1 when the larger urban tech-note transition to .rst is complete?

@olyson

olyson commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Would these steps be productive?

  1. create a documentation issue related to this PR
  2. merge this PR, and
  3. address step 1 when the larger urban tech-note transition to .rst is complete?

Sounds reasonable to me.

@slevis-lmwg

Copy link
Copy Markdown
Contributor

Would these steps be productive?

  1. create a documentation issue related to this PR
  2. merge this PR, and
  3. address step 1 when the larger urban tech-note transition to .rst is complete?

Sounds reasonable to me.

I can open the documentation issue right now.

@cathyxinchangli

Copy link
Copy Markdown
Contributor Author

Hi @samsrabin, I just pushed a commit that addressed the comments. The code produced bit-for-bit results compared with before the changes for short 2-day runs (case directories: /glade/derecho/scratch/xinchang/tmp/pr4164-review-cases/[case_name], output: /glade/derecho/scratch/xinchang/tmp/pr4164-review-simulations/[case_name]/run/. case_name is updated_mode[0,1,2] or baseline_mode[0,1,2]).

I look forward to your review!

@samsrabin

Copy link
Copy Markdown
Member

I'm assuming that was meant for @slevis-lmwg ?

@cathyxinchangli

Copy link
Copy Markdown
Contributor Author

Oops, you are right! Sorry @samsrabin and @slevis-lmwg!!

@github-project-automation github-project-automation Bot moved this to Stalled (needs review, blocked etc.) in CTSM: Upcoming tags Sep 9, 2026
@slevis-lmwg slevis-lmwg moved this from Stalled (needs review, blocked etc.) to In progress - master in CTSM: Upcoming tags Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement new capability or improved behavior of existing capability science Enhancement to or bug impacting science test: aux_clm Pass aux_clm suite before merging

Projects

Status: In progress - master
Status: In Progress

Development

Successfully merging this pull request may close these issues.

Representing indoor humidity and air-conditioning dehumidification in CLMU BEM

5 participants